OPC Studio User's Guide and Reference
Examples - OPC UA Alarms&Conditions - Subscribe to multiple events
View with Navigation Tools

.NET

// This example shows how to subscribe to multiple events.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.AlarmsAndConditions;
using OpcLabs.EasyOpc.UA.Filtering;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.AlarmsAndConditions
{
    class SubscribeMultipleMonitoredItems
    {
        public static void Events()
        {
            // Define which server we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

            // Instantiate the client object and hook events.
            var client = new EasyUAClient();
            client.EventNotification += client_EventNotification;

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments("firstState", 
                        endpointDescriptor, 
                        UAObjectIds.Server,
                        new UAMonitoringParameters(1000, new UAEventFilterBuilder(
                            UAFilterElements.GreaterThanOrEqual(UABaseEventObject.Operands.Severity, 500),
                            UABaseEventObject.AllFields)))
                        { AttributeId = UAAttributeId.EventNotifier },
                    new EasyUAMonitoredItemArguments("secondState",
                        endpointDescriptor, 
                        UAObjectIds.Server,
                        new UAMonitoringParameters(2000, new UAEventFilterBuilder(
                            UAFilterElements.Equals(
                                UABaseEventObject.Operands.SourceNode, 
                                new UANodeId("nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Metals/SouthMotor")),
                            UABaseEventObject.AllFields)))
                        { AttributeId = UAAttributeId.EventNotifier }
                });

            Console.WriteLine("Processing event notifications for 30 seconds...");
            System.Threading.Thread.Sleep(30 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_EventNotification(object sender, EasyUAEventNotificationEventArgs e)
        {
            // Display the event
            Console.WriteLine(e);
        }
        

        // Example output (truncated):
        //Subscribing...
        //Processing monitored item changed events for 30 seconds...
        //[firstState] Success
        //[secondState] Success
        //[firstState] Success; Refresh; RefreshInitiated
        //[firstState] Success; Refresh; (10 field results) [EastTank] 500! "The alarm was acknoweledged." @10/14/2019 4:00:13 PM
        //[firstState] Success; Refresh; (10 field results) [EastTank] 500! "The alarm was acknoweledged." @10/14/2019 4:00:17 PM
        //[firstState] Success; Refresh; (10 field results) [NorthMotor] 500! "The alarm was acknoweledged." @10/14/2019 4:00:02 PM
        //[firstState] Success; Refresh; (10 field results) [NorthMotor] 500! "The alarm was acknoweledged." @10/14/2019 4:00:16 PM
        //[firstState] Success; Refresh; (10 field results) [SouthMotor] 700! "The alarm was acknoweledged." @10/14/2019 4:00:21 PM
        //[firstState] Success; Refresh; (10 field results) [SouthMotor] 500! "The alarm was acknoweledged." @10/14/2019 4:00:03 PM
        //[firstState] Success; Refresh; RefreshComplete
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:08 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:08 PM
        //[secondState] Success; Refresh; RefreshInitiated
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 100! "The dialog was activated" @9/10/2019 8:08:25 PM
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 100! "The alarm is active." @11/8/2019 7:48:07 PM
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 700! "The alarm was acknoweledged." @10/14/2019 4:00:21 PM
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 500! "The alarm was acknoweledged." @10/14/2019 4:00:03 PM
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 100! "The alarm severity has increased." @9/10/2019 8:09:02 PM
        //[secondState] Success; Refresh; (10 field results) [SouthMotor] 100! "The alarm severity has increased." @9/10/2019 8:09:59 PM
        //[secondState] Success; Refresh; RefreshComplete
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:09 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:09 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:10 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:10 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:11 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:11 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:12 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:12 PM
        //[firstState] Success; (10 field results) [EastTank] 500! "The alarm severity has increased." @11/8/2019 7:48:13 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:13 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:13 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:14 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:14 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:15 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:15 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:16 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:16 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:17 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:17 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Raising Events" @11/8/2019 7:48:18 PM
        //[firstState] Success; (10 field results) [Internal] 500! "Events Raised" @11/8/2019 7:48:18 PM
        //[secondState] Success; (10 field results) [SouthMotor] 300! "The alarm severity has increased." @11/8/2019 7:48:18 PM
        //...
    }
}

COM

// This example shows how to subscribe to multiple events.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

type
  THelperMethods19 = class
    class function ObjectTypeIds_BaseEventType: _UANodeId; static;
    class function UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Time: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Message: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_AllFields: _UAAttributeFieldCollection; static;
  end;

type
  TClientEventHandlers19 = class
    procedure Client_EventNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUAEventNotificationEventArgs);
  end;

procedure TClientEventHandlers19.Client_EventNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUAEventNotificationEventArgs);
begin
  // Display the event
    WriteLn(eventArgs.ToString);
end;


class procedure SubscribeMultipleMonitoredItems.Events;
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers19;
  EndpointDescriptor: string;
  EventFilter1, EventFilter2: _UAEventFilter;
  MonitoredItemArguments1, MonitoredItemArguments2: _EasyUAMonitoredItemArguments;
  MonitoringParameters1, MonitoringParameters2: _UAMonitoringParameters;
  Operand11, Operand21: _UASimpleAttributeOperand;
  Operand12, Operand22: _UALiteralOperand;
  ServerNodeId1, ServerNodeId2: _UANodeId;
  SourceNodeId: _UANodeId;
  WhereClause1, WhereClause2: _UAContentFilterElement;
begin
  EndpointDescriptor := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';

  // set MonitoredItemArguments1
  // Event filter: The severity is >= 500.
  Operand11 := THelperMethods19.UABaseEventObject_Operands_Severity;
  Operand12 := CoUALiteralOperand.Create;
  Operand12.Value := 500;
  WhereClause1 := CoUAContentFilterElement.Create;
  WhereClause1.FilterOperator := UAFilterOperator_GreaterThanOrEqual;
  WhereClause1.FilterOperands.Add(Operand11);
  WhereClause1.FilterOperands.Add(Operand12);

  EventFilter1 := CoUAEventFilter.Create;
  EventFilter1.SelectClauses := THelperMethods19.UABaseEventObject_AllFields;
  EventFilter1.WhereClause := WhereClause1;

  ServerNodeId1 := CoUANodeId.Create;
  ServerNodeId1.StandardName := 'Server';

  MonitoringParameters1 := CoUAMonitoringParameters.Create;
  MonitoringParameters1.EventFilter := EventFilter1;
  MonitoringParameters1.QueueSize := 1000;
  MonitoringParameters1.SamplingInterval := 1000;

  MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments1.AttributeId := UAAttributeId_EventNotifier;
  MonitoredItemArguments1.EndpointDescriptor.UrlString := EndpointDescriptor;
  MonitoredItemArguments1.MonitoringParameters := MonitoringParameters1;
  MonitoredItemArguments1.NodeDescriptor.NodeId := ServerNodeId1;
  MonitoredItemArguments1.State := 'firstState';

  // set MonitoredItemArguments2
  // Event filter: The event comes from a specified source node.
  Operand21 := THelperMethods19.UABaseEventObject_Operands_SourceNode;
  SourceNodeId := CoUANodeId.Create;
  SourceNodeId.ExpandedText := 'nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Metals/SouthMotor';
  Operand22 := CoUALiteralOperand.Create;
  Operand22.Value := SourceNodeId;
  WhereClause2 := CoUAContentFilterElement.Create;
  WhereClause2.FilterOperator := UAFilterOperator_Equals;
  WhereClause2.FilterOperands.Add(Operand21);
  WhereClause2.FilterOperands.Add(Operand22);

  EventFilter2 := CoUAEventFilter.Create;
  EventFilter2.SelectClauses := THelperMethods19.UABaseEventObject_AllFields;
  EventFilter2.WhereClause := WhereClause2;

  ServerNodeId2 := CoUANodeId.Create;
  ServerNodeId2.StandardName := 'Server';

  MonitoringParameters2 := CoUAMonitoringParameters.Create;
  MonitoringParameters2.EventFilter := EventFilter2;
  MonitoringParameters2.QueueSize := 1000;
  MonitoringParameters2.SamplingInterval := 2000;

  MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments2.AttributeId := UAAttributeId_EventNotifier;
  MonitoredItemArguments2.EndpointDescriptor.UrlString := EndpointDescriptor;
  MonitoredItemArguments2.MonitoringParameters := MonitoringParameters2;
  MonitoredItemArguments2.NodeDescriptor.NodeId := ServerNodeId2;
  MonitoredItemArguments2.State := 'secondState';


  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers19.Create;
  Client.OnEventNotification := ClientEventHandlers.Client_EventNotification;

  Arguments := VarArrayCreate([0, 1], varVariant);
  Arguments[0] := MonitoredItemArguments1;
  Arguments[1] := MonitoredItemArguments2;

  WriteLn('Subscribing...');
  Client.SubscribeMultipleMonitoredItems(Arguments);

  WriteLn('Processing monitored item changed events for 30 seconds...');
  PumpSleep(30*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);

  WriteLn('Finished.');
  VarClear(Arguments);
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;

class function THelperMethods19.ObjectTypeIds_BaseEventType: _UANodeId;
  var NodeId: _UANodeId;
  begin
    NodeId := CoUANodeId.Create;
    NodeId.StandardName := 'BaseEventType';
    Result := NodeId;
  end;

class function THelperMethods19.UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand;
var
  BrowsePathParser: _UABrowsePathParser;
  Operand: _UASimpleAttributeOperand;
begin
  BrowsePathParser := CoUABrowsePathParser.Create;
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId := TypeId;
  Operand.QualifiedNames := BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
  Result := Operand;
end;

class function THelperMethods19.UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
var
  Operand: _UASimpleAttributeOperand;
begin
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId.StandardName := 'BaseEventType';
  Operand.AttributeId := UAAttributeId_NodeId;
  Result := Operand;
end;

class function THelperMethods19.UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventId');
end;

class function THelperMethods19.UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventType');
end;

class function THelperMethods19.UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode');
end;

class function THelperMethods19.UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName');
end;

class function THelperMethods19.UABaseEventObject_Operands_Time: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time');
end;

class function THelperMethods19.UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/ReceiveTime');
end;

class function THelperMethods19.UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/LocalTime');
end;

class function THelperMethods19.UABaseEventObject_Operands_Message: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message');
end;

class function THelperMethods19.UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity');
end;

class function THelperMethods19.UABaseEventObject_AllFields: _UAAttributeFieldCollection;
var
  Fields: _UAAttributeFieldCollection;
begin
  Fields := CoUAAttributeFieldCollection.Create;
  Fields.Add(UABaseEventObject_Operands_NodeId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventType.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceNode.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceName.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Time.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_ReceiveTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_LocalTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Message.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Severity.ToUAAttributeField);

  Result := Fields;
end;

 

See Also

Conceptual

Examples - OPC Alarms&Events